package com.jeecms.imax.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.List;
import java.util.Timer;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.jeecms.common.web.session.SessionProvider;
import com.jeecms.imax.util.AppTask;
import com.jeecms.imax.util.CacheUtils;
import com.jeecms.imax.util.CommonUtil;
import com.jeecms.imax.util.GsonUtil;
import com.jeecms.imax.util.HTTPClient;
import com.octo.captcha.service.image.ImageCaptchaService;

public class BaseHttpServlet extends HttpServlet {

	/**
	 * 注释内容
	 */
	private static final long serialVersionUID = -2480028329595450345L;

	protected static final Logger LOG = Logger.getLogger(BaseHttpServlet.class);

	protected static final HTTPClient HTTP_CLIENT = HTTPClient.getInstance();

	// private static final CacheManager manager = CacheUtils.getInstance();
	private static final Cache appCache = CacheUtils.getAppNameCacha();

	private static final Cache uriCache = CacheUtils.getAppUriCacha();

	private static final Cache serviceCache = CacheUtils.getServiceNameCacha();

	// protected static ServletContext CONTEXT;

	@Autowired
	private SessionProvider session;

	@Autowired
	private ImageCaptchaService imageCaptchaService;

	// private static final JsonObject headers = new JsonObject();

	@Override
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
		super.init(config);

		// headers.addProperty("Content-Type",
		// "application/x-www-form-urlencoded");
	}

	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String servletPath = getReqPath(req);

		JsonObject retObj = new JsonObject();

		if (checkToken(req)) {
			retObj.addProperty("retCode", 400101);
			retObj.addProperty("data", "token已过期");
			writeResult(resp, retObj);
			return;
		}
		LOG.info("Receive request " + servletPath + "?" + req.getQueryString());

		String url = "";
		if (servletPath.startsWith("/interface/refer/")) {
			url = InitServlet.paramsMap.get("developer-host2")
					+ InitServlet.paramsMap.get(servletPath) + "?";
		} else {
			url = InitServlet.paramsMap.get("developer-host")
					+ InitServlet.paramsMap.get(servletPath) + "?";
		}
		// String url = InitServlet.paramsMap.get("developer-host") +
		// InitServlet.paramsMap.get(servletPath) + "?";
		Enumeration<String> e = req.getParameterNames();

		while (e.hasMoreElements()) {
			String name = e.nextElement();
			url += name + "="
					+ CommonUtil.encodeWithUTF8(req.getParameter(name)) + "&";
		}

		LOG.info("Send to backend with url :" + url);

		JsonObject headers = new JsonObject();

		headers.addProperty("Content-Type", "application/x-www-form-urlencoded");

		JsonObject result = HTTP_CLIENT.doDELETE(url, headers);

		writeResult(resp, result.get("data").getAsString());
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		String servletPath = getReqPath(req);

		LOG.debug("interface path----" + servletPath);
		JsonObject retObj = new JsonObject();
		if (!servletPath.equals("/interface/logout")
				&& !servletPath.equals("/login")
				&& !servletPath.equals("/interface/register")
				&& !servletPath.equals("/interface/user/sendEmail")
				&& !servletPath
						.equals("/interface/refer/getAPIDocumentByServiceName")) {
			if (checkToken(req)) {
				retObj.addProperty("retCode", 400101);
				retObj.addProperty("data", "token已过期");
				writeResult(resp, retObj);
				return;
			}
		}

		if (servletPath.equals("/interface/application/checkname")
				|| servletPath.equals("/interface/application/checkuri")
				|| servletPath.equals("/interface/service/check")) {
			checkName(servletPath, req, resp);
			return;
		}

		LOG.info("Receive request " + servletPath + "?" + req.getQueryString());

		// String url = InitServlet.paramsMap.get("developer-host") +
		// InitServlet.paramsMap.get(servletPath) + "?" + req.getQueryString();

		String url = null;

		if (servletPath.equals("/interface/user")
				|| servletPath.equals("/interface/user/sendEmail")
				|| servletPath.equals("/interface/beta_user")) {
			url = InitServlet.paramsMap.get("user-profile-host")
					+ InitServlet.paramsMap.get(servletPath) + "?";
		} else if (servletPath.startsWith("/interface/refer/")) {
			url = InitServlet.paramsMap.get("developer-host2")
					+ InitServlet.paramsMap.get(servletPath) + "?";

		} else {
			url = InitServlet.paramsMap.get("developer-host")
					+ InitServlet.paramsMap.get(servletPath) + "?";
		}

		Enumeration<String> e = req.getParameterNames();

		while (e.hasMoreElements()) {
			String name = e.nextElement();
			url += name + "="
					+ CommonUtil.encodeWithUTF8(req.getParameter(name)) + "&";
		}

		// HttpSession session = req.getSession(false);
		// if (session != null && session.getAttribute("access_token") != null)
		// {
		// url += "access_token=" +
		// CommonUtil.encodeWithUTF8((String)(session.getAttribute("access_token")));
		// }

		LOG.info("Send to backend with url :" + url);

		JsonObject headers = new JsonObject();

		headers.addProperty("Content-Type", "application/x-www-form-urlencoded");

		JsonObject result = null;
		if (servletPath.contentEquals("/interface/app/delete")
				|| servletPath.contentEquals("/interface/service/del")
				|| servletPath.contentEquals("/interface/application/del")
				|| servletPath.contentEquals("/interface/CF/app/del")) {
			result = HTTP_CLIENT.doDELETE(url, headers);
			if (servletPath.contentEquals("/interface/application/del")
					&& result.get("retCode").getAsInt() == 200) {
				LOG.debug(" del app name = " + req.getParameter("appName")
						+ "del app uri" + req.getParameter("uriName"));

				appCache.remove(req.getParameter("appName"));
				LOG.debug("keys uriCache" + uriCache.getKeys());
				uriCache.remove(req.getParameter("uriName"));
				LOG.debug("keys uriCache2" + uriCache.getKeys());
			} else if (servletPath.contentEquals("/interface/service/del")
					&& result.get("retCode").getAsInt() == 200) {
				LOG.debug(" del service name = "
						+ req.getParameter("serviceName"));
				LOG.debug("keys servicecache" + serviceCache.getKeys());
				serviceCache.remove(req.getParameter("serviceName"));
				LOG.debug("keys servicecache2" + serviceCache.getKeys());
			}
		} else {
			result = HTTP_CLIENT.doGET(url, headers);
			JsonObject testUserObj = GsonUtil.convertString2Json(
					result.get("data").getAsString()).getAsJsonObject();
			if (servletPath.equals("/interface/beta_user")) {
				HttpSession session = req.getSession();
				if (testUserObj.get("ret").getAsInt() == 200) {
					JsonObject testUserData = testUserObj.get("data")
							.getAsJsonObject();
					LOG.debug("Receive dataresult from backend "
							+ testUserData.get("audit_state"));
					session.setAttribute("audit_state",
							testUserData.get("audit_state").getAsString());
				} else if (testUserObj.get("ret").getAsInt() == 400) {
					// System.out.println("-----4000");
					session.setAttribute("audit_state", "3");
				}
			}
		}
		LOG.debug("result----" + result);
		writeResult(resp,
				GsonUtil.convertString2Json(result.get("data").getAsString()));

	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		String servletPath = getReqPath(req);

		JsonObject retObj = new JsonObject();

		if (checkToken(req)
				&& !servletPath.contentEquals("/interface/refer/getability")
				&& !servletPath.contentEquals("/interface/refer/getCategoly")
				&& !servletPath.contentEquals("/interface/refer/IsSubscribe")
				&& !servletPath.contentEquals("/interface/refer/serchability")
				&& !servletPath
						.contentEquals("/interface/user/register_bymail")
				&& !servletPath.contentEquals("/interface/user/login_bymail")
				&& !servletPath.contentEquals("/interface/user/resetPwd")
				&& !servletPath
						.contentEquals("/interface/refer/getCategolyAndAbility")) {
			retObj.addProperty("retCode", 400101);
			retObj.addProperty("data", "token已过期");
			writeResult(resp, retObj);
			return;
		}

		if (servletPath.contentEquals("/interface/user/register_bymail")
				|| servletPath.contentEquals("/interface/user/login_bymail")) {
			String captcha = req.getParameter("captcha");
			HttpSession session = req.getSession();
			String tt = (String) session.getAttribute("randCheckCode");
			LOG.debug("get cpatcha-====" + captcha + "code session ++" + tt);
			// HttpSession session = req.getSession();
			if (!captcha.equalsIgnoreCase(tt)) {
				retObj.addProperty("ret", 400);
				retObj.addProperty("msg", "验证码错误");
				writeResult(resp, retObj);
				return;
			}
		}
		LOG.info("Receive request " + servletPath + "?" + req.getQueryString());
		String url = "";
		if (servletPath.startsWith("/interface/refer/")) {
			url = InitServlet.paramsMap.get("developer-host2")
					+ InitServlet.paramsMap.get(servletPath) + "?";
		} else if (servletPath.startsWith("/interface/user/")
				|| servletPath.equals("/interface/changepwd")
				|| servletPath.equals("/interface/user")
				|| servletPath.equals("/interface/beta_user")) {
			LOG.debug("uer profile host mothed ----" + servletPath);
			url = InitServlet.paramsMap.get("user-profile-host")
					+ InitServlet.paramsMap.get(servletPath) + "?";
		} else {
			url = InitServlet.paramsMap.get("developer-host")
					+ InitServlet.paramsMap.get(servletPath) + "?";
		}

		// String url = InitServlet.paramsMap.get("developer-host")
		// + InitServlet.paramsMap.get(servletPath) + "?";
		Enumeration<String> e = req.getParameterNames();

		while (e.hasMoreElements()) {
			String name = e.nextElement();
			url += name + "="
					+ CommonUtil.encodeWithUTF8(req.getParameter(name)) + "&";
		}

		BufferedReader br = req.getReader();
		StringBuffer sb = new StringBuffer();
		String content;
		while ((content = br.readLine()) != null) {
			sb.append(content);
		}

		// br.close();
		LOG.info("Send to backend with url :" + url + ",body :" + sb);

		JsonObject headers = new JsonObject();

		headers.addProperty("Content-Type", "application/json;charset=UTF-8");

		JsonObject result = null;
		if (servletPath.contentEquals("/interface/user")
				|| servletPath.contentEquals("/interface/app/edit")
				|| servletPath.contentEquals("/interface/application/alt")
				|| servletPath.contentEquals("/interface/application/order")
				|| servletPath.contentEquals("/interface/CF/app/update")) {

			result = HTTP_CLIENT.doPUT(url, sb.toString(), headers);
			writeResult(resp, result.get("data").getAsString());

			// 启动应用时，5分钟后如果没有启动成功则停止应用
			if (servletPath.contentEquals("/interface/application/order")) {
				timeTask(sb.toString(), req, resp);
			}
			return;
		} else {
			result = HTTP_CLIENT.doPOST(url, sb.toString(), headers);
			LOG.info(" post url result --" + result);
			writeResult(resp, GsonUtil.convertString2Json(result.get("data")
					.getAsString()));
		}
		LOG.debug("post result -----" + result.toString());

		JsonObject data = GsonUtil.convertString2Json(
				result.get("data").getAsString()).getAsJsonObject();

		if (servletPath.contentEquals("/interface/application/add")
				&& result.get("retCode").getAsInt() == 200) {
			JsonArray results = data.get("results").getAsJsonArray();
			LOG.debug("keys appcache" + appCache.getKeys());
			for (int i = 0; i < results.size(); i++) {
				JsonObject app = results.get(i).getAsJsonObject();
				Element element = new Element(app.get("appName").getAsString(),
						"1");
				appCache.put(element);
				Element uriEle = new Element(app.get("uri").getAsString(), "1");
				uriCache.put(uriEle);
			}
			LOG.debug("keys appcache" + appCache.getKeys());
		} else if (servletPath.contentEquals("/interface/service/add")
				&& result.get("retCode").getAsInt() == 200) {
			JsonArray results = data.get("results").getAsJsonArray();
			for (int i = 0; i < results.size(); i++) {
				JsonObject service = results.get(i).getAsJsonObject();
				Element element = new Element(service.get("servicename")
						.getAsString(), "1");
				serviceCache.put(element);
			}
		}

	}

	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		String servletPath = getReqPath(req);

		JsonObject retObj = new JsonObject();
		if (checkToken(req)) {
			retObj.addProperty("retCode", 400101);
			retObj.addProperty("data", "token已过期");
			writeResult(resp, retObj);
			return;
		}
		LOG.info("Receive request " + servletPath + "?" + req.getQueryString());

		String url = InitServlet.paramsMap.get("developer-host")
				+ InitServlet.paramsMap.get(servletPath) + "?";
		Enumeration<String> e = req.getParameterNames();

		while (e.hasMoreElements()) {
			String name = e.nextElement();
			url += name + "="
					+ CommonUtil.encodeWithUTF8(req.getParameter(name)) + "&";
		}

		BufferedReader br = req.getReader();
		StringBuffer sb = new StringBuffer();
		String content;
		while ((content = br.readLine()) != null) {
			sb.append(content);
		}

		LOG.info("Send to backend with url :" + url + ",body :" + sb);

		JsonObject headers = new JsonObject();

		headers.addProperty("Content-Type", "application/json;charset=UTF-8");

		JsonObject result = HTTP_CLIENT.doPUT(url, sb.toString(), headers);

		writeResult(resp, result.get("data").getAsString());
	}

	protected void writeResult(HttpServletResponse resp, Object result) {

		// resp.setCharacterEncoding("UTF-8");
		// resp.setHeader("Content-Type", "text/plain;charset=UTF-8");
		PrintWriter pw = null;

		try {
			pw = resp.getWriter();
			pw.println(result);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (pw != null) {
				pw.close();
			}
		}
	}

	protected boolean checkToken(HttpServletRequest req) {
		HttpSession session = req.getSession(false);
		if (session != null && session.getAttribute("access_token") != null) {
			return false;
		}
		return true;
	}

	protected String getReqPath(HttpServletRequest req) {
		String pathInfo = req.getPathInfo();
		String servletPath = req.getServletPath();
		if (pathInfo == null || pathInfo.equals("")) {
			return servletPath;
		} else if (servletPath == null || servletPath.equals("")) {
			return pathInfo;
		} else {
			return servletPath + pathInfo;
		}
	}

	protected void timeTask(String str, HttpServletRequest req,
			HttpServletResponse resp) {
		JSONObject obj = null;
		try {
			obj = new JSONObject(str);
			LOG.debug("receive post body ---" + obj);
			if (obj.get("order").toString().equals("1")) {
				AppTask appTask = new AppTask(obj.get("appName").toString(),
						req, resp);
				Timer timer = new Timer();
				// 5分钟
				timer.schedule(appTask, 5 * 60 * 1000);
			}
		} catch (JSONException e1) {
			e1.printStackTrace();
		}
	}

	protected void checkName(String servletPath, HttpServletRequest req,
			HttpServletResponse resp) {
		JsonObject retObj = new JsonObject();
		if (servletPath.equals("/interface/application/checkname")) {
			List appNames = appCache.getKeys();
			LOG.info("------element----"
					+ appCache.getKeys().contains(req.getParameter("appName")));
			if (appNames.contains(req.getParameter("appName"))) {
				retObj.addProperty("retCode", 302);
				retObj.addProperty("data", "应用名被占用");
				writeResult(resp, retObj);
				return;
			} else {
				retObj.addProperty("retCode", 200);
				retObj.addProperty("data", "应用名可用");
				writeResult(resp, retObj);
				return;
			}
		} else if (servletPath.equals("/interface/application/checkuri")) {
			List appUris = uriCache.getKeys();
			LOG.info("------element----"
					+ uriCache.getKeys().contains(req.getParameter("uri")));
			if (appUris.contains(req.getParameter("uri"))) {
				retObj.addProperty("retCode", 302);
				retObj.addProperty("data", "uri被占用");
				writeResult(resp, retObj);
				return;
			} else {
				retObj.addProperty("retCode", 200);
				retObj.addProperty("data", "uri可用");
				writeResult(resp, retObj);
				return;
			}
		} else if (servletPath.equals("/interface/service/check")) {
			List appUris = serviceCache.getKeys();
			LOG.info("------element----"
					+ serviceCache.getKeys().contains(
							req.getParameter("servicename")));
			if (appUris.contains(req.getParameter("servicename"))) {
				retObj.addProperty("retCode", 302);
				retObj.addProperty("data", "uri被占用");
				writeResult(resp, retObj);
				return;
			} else {
				retObj.addProperty("retCode", 200);
				retObj.addProperty("data", "uri可用");
				writeResult(resp, retObj);
				return;
			}
		}
	}
}
